package cn.iocoder.yudao.module.engine.controller.app.cosplay;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.engine.controller.app.cosplay.vo.AppCosplayListAllReqVO;
import cn.iocoder.yudao.module.engine.controller.app.cosplay.vo.AppCosplayOperationReqVO;
import cn.iocoder.yudao.module.engine.controller.app.cosplay.vo.AppCosplayRespVO;
import cn.iocoder.yudao.module.engine.controller.app.cosplayoperation.vo.AppCosplayOperationPageReqVO;
import cn.iocoder.yudao.module.engine.controller.app.cosplayoperation.vo.AppCosplayOperationSaveReqVO;
import cn.iocoder.yudao.module.engine.dal.redis.engine.EngineLockRedisDAO;
import cn.iocoder.yudao.module.resource.api.ICosplayApi;
import cn.iocoder.yudao.module.resource.api.ICosplayOperationApi;
import cn.iocoder.yudao.module.resource.api.model.CosplayDTO;
import cn.iocoder.yudao.module.resource.api.model.cosplayoperation.CosplayOperationDTO;
import cn.iocoder.yudao.module.resource.api.model.cosplayoperation.CosplayOperationPageReqDTO;
import cn.iocoder.yudao.module.resource.api.model.cosplayoperation.CosplayOperationSaveReqDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "App -CosPlay角色")
@RestController
@RequestMapping("/lm/cosplay")
@Validated
@Slf4j
public class AppCosplayController {
    @Resource
    private ICosplayApi cosplayApi;
    @Resource
    private ICosplayOperationApi cosplayOperationApi;
    @Resource
    private EngineLockRedisDAO lockRedisDAO;

    @PostMapping("/operation")
    @Operation(summary = "操作")
    @PreAuthenticated
    public CommonResult<Void> operation(@RequestBody @Valid AppCosplayOperationReqVO reqVO) {
        final Long userId = getLoginUserId();
        final Integer roleId = reqVO.getRoleId();

        return lockRedisDAO.lockRoleOperation(userId, roleId, () -> {
            final CosplayOperationDTO operation = cosplayOperationApi.getCosplayOperationByRoleId(userId, roleId);

            final AppCosplayOperationSaveReqVO saveReqVO = new AppCosplayOperationSaveReqVO();
            saveReqVO.setRoleId(roleId);

            if (reqVO.getFavorited() != null) {
                saveReqVO.setFavorited(reqVO.getFavorited());
            } else if (reqVO.getPlayed() != null) {
                saveReqVO.setPlayed(reqVO.getPlayed());
            }

            if (operation != null) {
                saveReqVO.setId(operation.getId());
                cosplayOperationApi.updateCosplayOperation(BeanUtils.toBean(saveReqVO, CosplayOperationSaveReqDTO.class));
            } else {
                final CosplayOperationSaveReqDTO reqDTO = BeanUtils.toBean(saveReqVO, CosplayOperationSaveReqDTO.class);
                reqDTO.setUserId(userId);
                cosplayOperationApi.createCosplayOperation(reqDTO);
            }

            return success(null);
        });
    }

    @GetMapping("/get")
    @Operation(summary = "获得角色")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthenticated
    public CommonResult<AppCosplayRespVO> getCosplay(@RequestParam("id") Integer id) {
        final Long userId = getLoginUserId();
        final CosplayDTO cosplay = cosplayApi.getCosplay(id);
        final AppCosplayRespVO respVO = BeanUtils.toBean(cosplay, AppCosplayRespVO.class);

        final CosplayOperationDTO operation = cosplayOperationApi.getCosplayOperationByRoleId(userId, id);
        respVO.setFavorited(operation != null && operation.getFavorited());
        respVO.setPlayed(operation != null && operation.getPlayed());

        return success(respVO);
    }

    @RequestMapping(value = "/list-all", method = {RequestMethod.GET, RequestMethod.POST})
    @Operation(summary = "获得角色分页")
    @PreAuthenticated
    public CommonResult<List<AppCosplayRespVO>> listAll(@RequestBody(required = false) @Valid AppCosplayListAllReqVO reqVO) {
        final List<CosplayDTO> dtoList = cosplayApi.getAllCosplay(reqVO.getShowLocation());
        final List<AppCosplayRespVO> voList = BeanUtils.toBean(dtoList, AppCosplayRespVO.class);

        final Long userId = getLoginUserId();
        final Map<Integer, CosplayOperationDTO> roleId2OperationMap = getRoleId2OperationMap(userId);
        for (AppCosplayRespVO role : voList) {
            final CosplayOperationDTO cosplayOperation = roleId2OperationMap.get(role.getId());
            role.setFavorited(cosplayOperation != null && cosplayOperation.getFavorited());
            role.setPlayed(cosplayOperation != null && cosplayOperation.getPlayed());
        }

        if (reqVO != null && reqVO.getFavorited() != null) {
            // 过滤收藏的角色
            voList.removeIf(role -> !role.getFavorited());
        } else if (reqVO != null && reqVO.getPlayed() != null) {
            // 过滤玩过的角色
            voList.removeIf(role -> !role.getPlayed());
        }

        return success(voList);
    }

    @NotNull
    private Map<Integer, CosplayOperationDTO> getRoleId2OperationMap(Long userId) {
        final Map<Integer, CosplayOperationDTO> roleId2OperationMap = new HashMap<>();

        final AppCosplayOperationPageReqVO operationPageReqVO = new AppCosplayOperationPageReqVO();
        operationPageReqVO.setPageNo(1);
        operationPageReqVO.setPageSize(Integer.MAX_VALUE);
        final PageResult<CosplayOperationDTO> operationPage = cosplayOperationApi.getCosplayOperationPage(userId, BeanUtils.toBean(operationPageReqVO, CosplayOperationPageReqDTO.class));
        final List<CosplayOperationDTO> operationList = operationPage.getList();
        if (CollUtil.isNotEmpty(operationList)) {
            for (CosplayOperationDTO cosplayOperationDO : operationList) {
                roleId2OperationMap.put(cosplayOperationDO.getRoleId(), cosplayOperationDO);
            }
        }

        return roleId2OperationMap;
    }

}